/*
 * Alignment
 */


#include "resed.h"


/*
 * Align the selected items according to 'how', which will contain
 * one of the ALIGNMENU_ constants from align.h, or -1 for no-op.
 */

error * align_selection (ResourcePtr res, ItemInfoPtr key, int how)
{
    ItemInfoPtr item;
    RectRec bbox, damage = {1000000, 1000000, -1000000, -1000000};
    int i, keypos, baseline, dummy;

    if (key == NULL || how == -1)
        return NULL;

    /* Determine align position according to alignment edge */

    template_item_bbox (res, key, &bbox);
    switch (how)
    {
    case ALIGNMENU_LEFT:
        keypos = bbox.minx; break;
    case ALIGNMENU_HCENT:
        keypos = (bbox.minx + bbox.maxx) / 2; break;
    case ALIGNMENU_RIGHT:
        keypos = bbox.maxx; break;
    case ALIGNMENU_BOTTOM:
        keypos = bbox.miny; break;
    case ALIGNMENU_VCENT:
        keypos = (bbox.miny + bbox.maxy) / 2; break;
    case ALIGNMENU_TOP:
        keypos = bbox.maxy; break;
    case ALIGNMENU_BASELINE:
        grid_snap_offset (res, key, &bbox, &dummy, &keypos);
        keypos += bbox.miny;
        break;
    }

    /* Now ensure that keypos is a pixel multiple */

    switch (how)
    {
    case ALIGNMENU_LEFT:  case ALIGNMENU_RIGHT:  case ALIGNMENU_HCENT:
        keypos >>= scalex; keypos <<= scalex;
        break;
    default:
        keypos >>= scaley; keypos <<= scaley;
        break;
    }

    /* Loop over all selected items and align */
    
    for (i = 0; i < res->numicons; i++)
    {
        if ((item = res->icons[i].owner) != NULL &&
            item != key &&
            item->u.master == i && item->selected)
        {
            template_item_bbox (res, item, &bbox);
            wimp_merge_bboxes (&damage, &damage, &bbox);
            
            switch (how)
            {
            case ALIGNMENU_LEFT:
                grid_move_item (res, item, keypos - bbox.minx, 0);
                break;
            case ALIGNMENU_RIGHT:
                grid_move_item (res, item, keypos - bbox.maxx, 0);
                break;
            case ALIGNMENU_HCENT:
                grid_move_item (res, item, keypos - (bbox.minx + bbox.maxx) / 2, 0);
                break;
            case ALIGNMENU_TOP:
                grid_move_item (res, item, 0, keypos - bbox.maxy);
                break;
            case ALIGNMENU_BOTTOM:
                grid_move_item (res, item, 0, keypos - bbox.miny);
                break;
            case ALIGNMENU_VCENT:
                grid_move_item (res, item, 0, keypos - (bbox.miny + bbox.maxy) / 2);
                break;
            case ALIGNMENU_BASELINE:
                grid_snap_offset (res, item, &bbox, &dummy, &baseline);
                baseline += bbox.miny;
                grid_move_item (res, item, 0, keypos - baseline);
                break;
            }
            
            template_item_bbox (res, item, &bbox);
            wimp_merge_bboxes (&damage, &damage, &bbox);
        }
    }

    template_adjust_item_bbox (AddHighlight, &damage, &damage);
    wimp_invalidate (&res->window, &damage);

    return document_modified (res->owner, TRUE);
}

